package com.caiyouxi.finance.service;

import com.alibaba.fastjson.JSONObject;
import com.caiyouxi.common.Constant;
import com.caiyouxi.common.bean.QueryParams;
import com.caiyouxi.common.bean.ResData;
import com.caiyouxi.common.cache.RedisService;
import com.caiyouxi.common.service.BaseService;
import com.caiyouxi.common.util.Log;
import com.caiyouxi.finance.mapper.FinanceAccountMapper;
import com.caiyouxi.finance.mapper.FinanceCurrencyMapper;
import com.caiyouxi.finance.model.FinanceAccount;
import com.caiyouxi.finance.model.FinanceAccountDetail;
import com.caiyouxi.finance.model.FinanceCurrency;
import com.caiyouxi.finance.model.FinanceTradeReceivable;
import com.caiyouxi.goods.mapper.GoodsInfoMapper;
import com.caiyouxi.goods.model.GoodsInfo;
import com.caiyouxi.goods.service.GoodsDeliverServiceService;
import com.caiyouxi.goods.service.GoodsInfoService;
import com.caiyouxi.order.model.OrderBean;
import com.caiyouxi.order.service.OrderService;
import com.caiyouxi.pay.model.PayTypeBean;
import com.caiyouxi.pay.service.PayServiceImpl;
import com.caiyouxi.system.mapper.SettingsMapper;
import com.caiyouxi.user.model.UserReserved;
import com.caiyouxi.user.service.UserReservedService;
import com.caiyouxi.util.NumUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;


/**
 * 用户账户款项
 * chensong
 */
@Service
public class FinanceAccountService extends BaseService {
    
    @Autowired
    private FinanceAccountMapper financeAccountMapper;
    @Autowired
    private FinanceCurrencyMapper financeCurrencyMapper;
    @Autowired
    private FinanceAccountDetailService financeAccountDetailService;
    @Autowired
    private GoodsInfoMapper goodsInfoMapper;
    @Autowired
    private SettingsMapper settingsMapper;
    @Autowired
    private UserReservedService userReservedService;
    @Autowired
    private FinanceCurrencyService financeCurrencyService;
    @Autowired
    private GoodsInfoService goodsInfoService;
    @Autowired
    private GoodsDeliverServiceService goodsDeliverServiceService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private PayServiceImpl payService;
    @Autowired
    private RedisService redisService;


    /**
     * 查询用户账户信息
     * select_finance_account_by_user_id_and_currency_code_and_account_code
     */
    public FinanceAccount select_finance_account_by_uiaccaac(String currency_code,String account_code,Integer user_id){
        HashMap<String, Object> map = new HashMap();
        map.put("user_id",user_id);
        map.put("currency_code",currency_code);
        map.put("account_code",account_code);
        FinanceAccount fa = financeAccountMapper.select_finance_account_by_uiaccaac(map);

        if(fa == null){
            boolean flag = false;
            if("PRIMARY".equals(account_code)){
                flag = true;
            }
            fa = add_finance_account(user_id,account_code,currency_code,0,flag,"初始化用户");
        }
        return fa;
    }
    
    /**
     * 校验买家用户账户
     * @param bean
     * @return
     */
    public boolean check_buy_finance_account_mess(OrderBean bean){
        FinanceAccount fa = select_finance_account_by_uiaccaac(bean.getCurrency_code(),bean.getAccount_code(),bean.getBuyer_user_id());
        if(!Constant.USE_ACC_STATUS_NORMAL.equals(fa.getStatus())){
            //买家账户异常
            Log.d("买家账户异常" + fa.getStatus());
            return false;
        }
        return true;
    }

    /**
     * 校验卖家用户账户
     * @param bean
     * @return
     */
    public boolean check_sell_finance_account_mess(OrderBean bean){
        FinanceAccount fa = select_finance_account_by_uiaccaac(bean.getCurrency_code(),bean.getAccount_code(),bean.getSeller_user_id());
        if(!Constant.USE_ACC_STATUS_NORMAL.equals(fa.getStatus())){
            //卖家账户异常
            Log.d("卖家账户异常" + fa == null ? "" : fa.getStatus());
            return false;
        }
        return true;
    }

    /**
     * 新建用户账户信息
     * @param userId
     * @param account_code
     * @param currency_code
     * @param balance
     * @param specify
     * @param remark
     * @return
     */
    public FinanceAccount add_finance_account(Integer userId,String account_code,String currency_code,Integer balance,boolean specify,String remark){
        FinanceAccount fa = new FinanceAccount();
        fa.setUser_id(userId);
        fa.setAccount_code(account_code);
        fa.setCurrency_code(currency_code);
        fa.setBalance(balance);
        fa.setSpecify(specify);
        fa.setId(Integer.valueOf(NumUtil.generate_number_on_int(3)));
        fa.setStatus(Constant.USE_ACC_STATUS_NORMAL);//正常
        fa.setCheck_time(new Date());
        fa.setCreate_time(new Date());
        fa.setUpdate_time(new Date());
        fa.setRemark(remark);
        financeAccountMapper.add_finance_account(fa);
        return fa;
    }

    /**
     * 更新用户账户 信息
     */
    public void update_finance_account(FinanceAccount fa){
        financeAccountMapper.update_finance_account(fa);
    }

    /**
     * 发货————含处理余额充值业务，给用户加款
     * flag   货币类型转换 false转换true不转换
     */
    public HashMap<String,Object> update_finance_account_balance(OrderBean order,FinanceTradeReceivable ftr,boolean flag){
        HashMap<String,Object> map = new HashMap();
        String msg = "成功";
        String code="SUCCESS";
        //原货币类型余额减sell_currency_code
        String currency_code = null;
        FinanceCurrency financeCurrency = null;
        Integer buy_user_id = order.getBuyer_user_id();
        if(flag){
            //非充值，则将加到对应商品卖家账户
            buy_user_id = order.getSeller_user_id();
            Log.d("买家入款开始" + "商户加款" + buy_user_id);
        }else{
            //充值，则将加到对应买家账户
            Log.d("买家入款开始" + "用户充值" + buy_user_id);
        }
        //查询用户账户余额，加
        FinanceAccount fa_buy = select_finance_account_by_uiaccaac(order.getCurrency_code(),order.getAccount_code(),buy_user_id);
        if(fa_buy == null){
            Log.e("收款账户异常");
            msg="账户状态异常!";
            code="FAILD";
        }
        if(!"NORMAL".equals(fa_buy.getStatus())){
            //账户状态异常
            Log.d("收款账户状态异常（买家）");
            msg="账户状态异常!";
            code="FAILD";
        }
        financeCurrency = financeCurrencyMapper.select_finance_currency(order.getCurrency_code());//获取对应货币类型
        if(financeCurrency == null){
            //货币类型不存在
            Log.e("货币类型不存在");
            msg="账户状态异常!";
            code="FAILD";
        }
        Integer amount = 0;
        if(!flag){
            //涉及货币类型转换，说明是余额充值
            if("RMB".equals(financeCurrency.getBuying_currency_type())){
                //卖家为内置账户   即对应的内置商品的sell_user_id
                //人民币充值  取0账户，直接给用户余额加款
                HashMap<String,Object> map1 = update_finance_account(fa_buy,order.getBuyer_user_id(),order.getTotal_amount(),Constant.USER_STATUS_CONFIRMED,order.getAccount_code(),ftr.getId(),ftr.getFinance_trade_details_id());
                if(!"SUCCESS".equals(map1.get("code"))){
                    return map1;
                }
            }
            currency_code = financeCurrency.getBuying_currency_type();
            amount = order.getTotal_amount() * financeCurrency.getRate();
            Log.e("转换货币类型");
        }else{
            currency_code = order.getCurrency_code();
//            seller_user_id = order.getSeller_user_id();
            amount = order.getTotal_amount();
        }
        GoodsInfo gInfo = goodsInfoMapper.select_goods_info(Long.valueOf(financeCurrency.getRecharge_goods_id()));
        //商品的卖家发行账户
        FinanceAccount fa_sell = select_finance_account_by_uiaccaac(currency_code,order.getAccount_code(),gInfo.getSeller_user_id());
        if(fa_sell == null){
            Log.e("出款账户异常（卖家）");
            msg="账户状态异常!";
            code="FAILD";
        }
        if(fa_sell.getBalance() < order.getTotal_amount()){
            //卖家余额小于需扣除的金额
            Log.d("余额不足，余额" + fa_sell.getBalance() + "货币：" + order.getCurrency_code());
            msg="余额不足!";
            code="FAILD";
        }
        if(!"NORMAL".equals(fa_sell.getStatus())){
            //账户状态异常
            Log.d("出款账户状态异常（卖家）");
            msg="账户状态异常!";
            code="FAILD";
        }
        //说明：需要抵扣的上一级金额 = 需要充值的金额 / 对应的兑率

        //生成对应的账户流水记录
        //卖家出款   扣款order.getTotal_amount()/financeCurrency.getRate()
        HashMap<String,Object> map2 = update_finance_account(fa_sell,gInfo.getSeller_user_id(),- order.getTotal_amount(),Constant.USER_STATUS_CONFIRMED,order.getAccount_code(),ftr.getId(),ftr.getFinance_trade_details_id());
        Log.d("卖家出款结束" + "内置账户减款" + gInfo.getSeller_user_id());
        if(!"SUCCESS".equals(map2.get("code"))){
            return map2;
        }
        Log.e("换算后的需充值的目标货币金额" + order.getTotal_amount() * financeCurrency.getRate() + "兑率：" + financeCurrency.getRate());
        //买家入款
        HashMap<String,Object> map3 = update_finance_account(fa_buy,buy_user_id,amount,Constant.USER_STATUS_CONFIRMED,order.getAccount_code(),ftr.getId(),ftr.getFinance_trade_details_id());
        if(!"SUCCESS".equals(map3.get("code"))){
            return map3;
        }

        map.put("code",code);
        map.put("msg",msg);
        return map;
    }

    /**
     * 账户变更，增加流水，更新账户信息
     */
    @Transactional
    public HashMap<String,Object> update_finance_account(FinanceAccount fa,Integer userId,Integer totalAmount,String status,String account_code,BigInteger ftr_id,BigInteger ftr_trade_detail_id){
        HashMap<String,Object> map = new HashMap();
        Log.d("充值前余额" + fa.getBalance());
        Log.d("充值金额" + totalAmount);
        if((fa.getBalance() + totalAmount) < 0){
            //说明支付不足
            Log.e("说明支付不足");
            map.put("code","PAY_ERROR_BALLANCE_LOW");
            map.put("msg","余额不足");
            return map;
        }
        FinanceAccountDetail fad = financeAccountDetailService.add_finance_account_details(new BigInteger(fa.getId().toString()),userId,account_code,fa.getBalance(),totalAmount,ftr_id,ftr_trade_detail_id);
        //更新余额
        Log.d("充值后余额" + (fa.getBalance() + totalAmount));
        fa.setBalance(fa.getBalance() + totalAmount);
        fa.setUpdate_time(new Date());
        fad.setStatus(status);//已经确认完成的
        fad.setUpdate_time(new Date());
        
        //入款时加判断，如果是虚拟货币充值，更新对应用户账户虚拟币余额的有效期
        if(totalAmount > 0){
            //先判断是否是内置账户——查询内置账户表
            UserReserved userReserved = userReservedService.get_user_reserved_by_user_id(fa.getUser_id().toString());
            if(userReserved == null){
                //非内置账户，需更新对应账户有效时间
                
                //说明是入款，充值
                String key = null;//虚拟币，非余额
                if("CASH".equals(fa.getCurrency_code())){
                    key = "sys.usemaindays";//虚拟币，余额
                }else{
                    //虚拟币，非余额
                    key = "sys.usedays";
                }
                String select_setting = (String) redisService.get(key);
                if(select_setting == null){
                    select_setting = settingsMapper.select_setting(key).getValue();
                    redisService.set(key,select_setting);
                }
                Calendar c = Calendar.getInstance();
                c.add(Calendar.DATE,Integer.valueOf(select_setting));
                fa.setUse_expire_time(c.getTime());       
            }else{
                //说明是内置账户，无需更新有效期
                Log.e("内置账户，无需更新有效期");
            }
        }
        financeAccountMapper.update_finance_account(fa);//更新账户余额
        
        financeAccountDetailService.update_finance_account_details(fad);
        map.put("code","SUCCESS");
        map.put("msg","成功");
        return map;
    }

    /**
     * 处理对应的账户信息
     */
    public HashMap<String,Object> check_account_balance(OrderBean order,FinanceTradeReceivable ftr){
        HashMap<String,Object> map = new HashMap();
        String msg = "成功";
        String code="SUCCESS";
        if("RECHARGE".equals(ftr.getFund_type())) {
            //账户充值   涉及货币类型转换
            //从内置账户cash账户凭空加，最终转至对应订单的买家current_code账户余额
            HashMap<String,Object> map1 = update_finance_account_balance(order,ftr,false);
            if(!"SUCCESS".equals(map1.get("code"))){
                //充值异常
                Log.d("充值异常");
                return map1;
            }
        }else{
            //创建用户账户款流水记录
            HashMap<String,Object> map2 = update_finance_account_balance(order,ftr,true);
            if(!"SUCCESS".equals(map2.get("code"))){
                //购买异常
                Log.d("购买异常");
                return map2;
            }
        }
        map.put("code",code);
        map.put("msg",msg);
        return map;
    }

    /**
     * 给用户购买前台商品的货币类型的账户余额充值（JCD,CB），非CASH,应该是虚拟币
     */
    public void user_account_balance_recharge(OrderBean user_order,GoodsInfo user_goods) {

        //说明当前用户cash账户已有余额充值进来，要转至目标货币类型的账户余额上
        FinanceCurrency f_up = financeCurrencyService.get_fcurrency_by_buying_type("CASH");
        if(f_up != null){
            Integer amount = user_order.getTotal_amount();
            user_recharge(f_up,user_goods,user_order,amount);
        }
     
    }

    //递归循环，充值对应用户的对等货币单位的余额
    public void user_recharge(FinanceCurrency f_up,GoodsInfo user_goods,OrderBean user_order,Integer amount){
        if(f_up.getCode().equals(user_goods.getCurrency_code())){
            //表示对应的的货币类型一致
            financeCurrenctChange(f_up.getBuying_currency_type(),f_up,amount,user_order.getBuyer_user_id(),user_order.getAccount_code());
            
        }else{
            FinanceCurrency f_down = financeCurrencyService.get_fcurrency_by_buying_type(f_up.getCode());
            //不一致，先将f_up货币类型余额转换至下一级货币单位余额——即购买下一级货币类型商品
            financeCurrenctChange(f_up.getCode(),f_down,amount,user_order.getBuyer_user_id(),user_order.getAccount_code());
            
            user_recharge(f_down,user_goods,user_order,amount);
        }

    }
    
    public void financeCurrenctChange(String currency_code,FinanceCurrency f_down,Integer amount,Integer user_id,String account_code){
        //货币类型不一致，则下单层级往下充值
        //下单——（购买下一级货币类型的商品）
        OrderBean recharge_order = new OrderBean();
        recharge_order.setTitle("货币类型转换——内部充值");
        recharge_order.setCurrency_code(f_down.getCode());//目标货币单位
        recharge_order.setTotal_amount(amount);//支付的金额
        recharge_order.setAccount_code(account_code);
        recharge_order.setBuyer_user_id(user_id);
        recharge_order.setGoods_id(f_down.getRecharge_goods_id());//需购买的商品——充值
        recharge_order.setUp_curreny_code(currency_code);//当前货币单位
        JSONObject jon = new JSONObject();
        jon.put("RECHARGE",amount * f_down.getRate());//充值目标金额
        recharge_order.setFund_json(jon.toJSONString());

        Log.e("下单开始");
        OrderBean ob = orderService.add_order(recharge_order);
        Log.e("下单结束");

        //下单结束后，调支付
        PayTypeBean ptb = new PayTypeBean();
        ptb.setOrder_id(ob.getId());
        ptb.setProvider("ACCOUNT");//余额支付————直接发货
        ptb.setPay_id("9999");
        ptb.setAmount(ob.getTotal_amount());
        //将用户的对应的支付余额减，加至对应的我方货币类型的内置余额账户
        ptb.setUp_curreny_code(currency_code);
        payService.pay(ptb);
        //其中调发货服务（即内置账户换算后加至用户）
    }

    /**
     * wushihao
     * 分页查询
     * */
    public ResData finance_account_list(FinanceAccount bean){
        QueryParams pageList = new QueryParams();
        if (bean.getPage_size() == 0){
            bean.setPage_size(Integer.parseInt(redisService.get("sys.pagesize").toString()));
        }
        pageList.setPage_size(bean.getPage_size());
        pageList.setPage(bean.getPage());
        pageList.setTotal(financeAccountMapper.finance_account_counts(bean));
        pageList.setList(financeAccountMapper.finance_account_list(bean));
        return success(pageList);
    }

}

